package com.cyf.plc.data.repository

import com.cyf.plc.util.State
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.flow
import retrofit2.Response

/**
 * A repository which provides resource from local database as well as remote end point.
 *
 * [RESULT] represents the type for database.
 * [REQUEST] represents the type for network.
 */
@ExperimentalCoroutinesApi
abstract class NetworkBoundRepository<RESULT> {

    fun asFlow() = flow<State<RESULT>> {

        // Emit Loading State
        emit(State.loading())

        try {

            // Fetch latest posts from remote
            val apiResponse = fetchFromRemote()

            // Parse body
            val body = apiResponse.body()

            // Check for response validation
            if (apiResponse.isSuccessful && body != null) {
                // Save posts into the persistence storage
                emit(State.success(body))
            } else {
                // Something went wrong! Emit Error state.
                emit(State.error(apiResponse.message()))
            }

        } catch (e: Exception) {
            // Exception occurred! Emit error
            emit(State.error("Network error!"))
            e.printStackTrace()
        }

    }

    abstract suspend fun fetchFromRemote(): Response<RESULT>

}